package ganga.custodian;

import ganga.custodian.BluetoothManager.BluetoohException;
import ganga.custodian.human.EmergencyDetector;
import ganga.custodian.human.HumanModel;
import ganga.custodian.human.IntervalCardiogram;
import ganga.custodian.notification.NotificationExecutor;
import ganga.custodian.persistence.Database;
import ganga.custodian.sensors.AccelerometerMonitor;
import ganga.custodian.sensors.HeartBeatService;
import ganga.custodian.utils.Theme;

import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.widget.Toast;

import java.util.List;

/**
 * Application class works as a dock for other components.
 * It share data across multiple Activities and Services.
 * Realized as singleton.
 * When writing an Android app, you're guaranteed to only have one instance 
 * of the android.app. Application class so it's safe 
 * ( and recommended by the Google Android team ) to treat it as a Singleton.
 * 
 * @see http://www.androidcookbook.com/Recipe.seam?recipeId=1218
 * 
 * @author Apocrypha
 */
public final class CustodianApplication extends android.app.Application {

	private Context context = this;
	public Database database;
	
	//TODO:Аутентифицированный пользователь
	
	public HumanModel humanModel;
	public NotificationExecutor notificationExecutor;
	//public LocationManager locationManager;
	public SensorManager sensorManager;
	public List<Sensor> accelerometrs;
	public List<Sensor> orientations;
	public List<Sensor> gyroscopes;
	public Theme selectTheme;

	public EmergencyDetector emergencyDetector;
	public AccelerometerMonitor accelerometerMonitor;
	//public CardioMonitor
	public IntervalCardiogram cardiogram;
	public String cardioMonitor;
	
	public synchronized BluetoothManager getBluetoothManager() {
		if (bluetoothManager==null)
			try {
				bluetoothManager = new BluetoothManager(null);
			} catch (Exception ex) {
				ex.printStackTrace();
				showToast(ex.getMessage());
				return null;
			}
		
		return bluetoothManager;
	}

	/**
     * Data units.
     */
     public static enum Unit {
        SI, IMPERIAL;
    }

	private void initialize(){
		new DataServiceTask().execute();
		emergencyDetector = new EmergencyDetector();
	}
	private void initializeSensors(){
		sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
		accelerometrs = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
		orientations = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
		gyroscopes = sensorManager.getSensorList(Sensor.TYPE_GYROSCOPE);
		
		accelerometerMonitor = new AccelerometerMonitor(this);
		// Start accelerometerMonitor
		Sensor sensor = sensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		if (sensor != null) {
			boolean running = sensorManager.registerListener(accelerometerMonitor,
					sensor, SensorManager.SENSOR_DELAY_UI);
		}
	}
	private void  initializeCardioMonitor(){
		cardiogram = new IntervalCardiogram();
		//Observer 
		//cardiogram.addObserver();
		cardioMonitor = "Не выбран";
		
	}
	private void initializeBlueTooth(){
		
	}

	/**
	 * Implementations should be as quick as possible (for example using lazy
	 * initialization of state) since the time spent in this function directly
	 * impacts the performance of starting the first activity, service, or
	 * receiver in a process. 
	 * 
	 * @see android.app.Application#onCreate()
	 * @see ganga.custodian.CustodianService
	 */
	@Override
	public final void onCreate() {
		super.onCreate();
		instance = this;
		instance.initialize();
		instance.initializeSensors();
		database = new Database(context);
		humanModel = new HumanModel();
		notificationExecutor = new NotificationExecutor(this);
		selectTheme= new Theme();
	}

	/**
	 * Can be called when the application object is terminated. 
	 * Note that there is no guarantee of this method handler�s being called.
	 * If the application is terminated by the kernel in order to free resources
	 * for other applications, the process will be terminated without warning and
	 * without a call to the application object�s onTerminate handler.
	 * 
	 * @see android.app.Application#onTerminate()
	 */
	@Override
	public final void onTerminate() {
		//TODO specify name for stopService(name) 
		stopService(null);
		database.close();
		super.onTerminate();
	}

	@Deprecated
	public String getRes(int resId) {
		return getString(resId);
	}
	/**
	 * Show message by pop-up toast
	 * @param message
	 */
	public void showToast(String message) {
		Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
	}

	/**
	 * Singleton
	 */
	private static CustodianApplication instance;
	/**
	 * Returns the application instance
	 */
	public static CustodianApplication getInstance() {
		return instance;
	}

	/**
	 * @return true if  
	 */
	public boolean useBlueTooth() {
		if (!useBlueTooth)
			return false;
		if (bluetoothManager == null)
			try {
				bluetoothManager = new BluetoothManager(activity);
			} catch (BluetoohException ex) {
				useBlueTooth = false;
			}
		return useBlueTooth;
	}

	private class DataServiceTask extends AsyncTask <Void,Void,Void>{

		@Override
		protected Void doInBackground(Void... arg0) {
			Intent startServiceIntent = new Intent(context, HeartBeatService.class);
			startService(startServiceIntent);
			return null;
		}		
	} //DataServiceTask

	private MainActivity activity;
	public BluetoothManager bluetoothManager;
	private boolean useBlueTooth = true;

	// Debugging
    private static final String TAG = "Custodian App";
	protected static final boolean DEBUG = true;
}//CustodianApplication